using System;
using System.Windows.Controls;
using Phoenix.Frames;
using Phoenix.Framework;

namespace Phoenix.ActionResults
{
    /// <summary>
    /// View Result is base class for action results displaying views
    /// </summary>
    public abstract class ViewActionResult : ActionResult, IHaveInvokeCompletedSteps
    {
        Control view;

        /// <summary>
        /// Initializes a new instance of the <see cref="ViewActionResult"/> class.
        /// </summary>
        /// <param name="viewName">Name of displayed view.</param>
        /// <param name="viewModel">Viewmodel.</param>
        /// <param name="context">Navigation ontext.</param>
        protected ViewActionResult(string viewName, ViewModelBase viewModel, ControllerActionContext context)
            : base(context)
        {
            ViewName = viewName;
            ViewModel = viewModel ?? new DefaultViewModel();
            if (ViewModel != null)
                ViewModel.Context = context;
        }

        /// <summary>
        /// Gets name of the view.
        /// </summary>
        /// <value>The of the view.</value>
        public string ViewName { get; private set; }

        /// <summary>
        /// Gets (view)model.
        /// </summary>
        /// <value>The (view)model.</value>
        public ViewModelBase ViewModel { get; private set; }

        /// <summary>
        /// Executes result.
        /// </summary>
        /// <param name="targetFrame"> </param>
        public override void Execute(IContentFrame targetFrame)
        {
            TargetFrame = targetFrame;
            if (ViewModel != null)
            {
#if WINDOWS_PHONE
                ViewModel.TaskManager = Context.Host.TaskManager;
#endif
                ViewModel.PageState = Context.RequestState;
                ViewModel.ApplicationState = Context.Host.ApplicationTransientState;
                ViewModel.EventAggregator = Context.Host.EventAggregator;
            }

            var viewLocator = Context.Host.ViewLocator;
            var controllerAction = new ControllerAction(Context.ControllerAction.Controller, ViewName, Context.ControllerAction.Assembly);
            view = viewLocator.Locate(controllerAction);
            view.DataContext = ViewModel;
            view.Name = ViewName;
        }

        protected IContentFrame TargetFrame { get; private set; }

        public void InvokeComplete()
        {
            RenderView(view);
        }

        protected abstract void RenderView(Control view);
    }
}